package com.ssy.lingxi.member.merchant.utils;

import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.CountryAreaDO;
import com.ssy.lingxi.member.merchant.model.bo.AgentAreaBO;
import com.ssy.lingxi.member.merchant.model.bo.AreaBO;
import com.ssy.lingxi.member.merchant.model.constant.MemberStringEnum;
import com.ssy.lingxi.member.merchant.model.dto.CountryAreaDTO;
import com.ssy.lingxi.member.merchant.model.vo.basic.request.AreaCodeVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.AreaCodeQueryVO;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.CountryAreaVO;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 渠道会员代理区域编码辅助类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-05-21
 */
public class AgentAreaUtil implements Serializable {
    private static final long serialVersionUID = 2191622412667696760L;

    /**
     * 将省市DO列表转换为VO列表
     * @param areaDOList 接口参数
     * @return 操作结果
     */
    public static List<CountryAreaVO> transferToVO(List<CountryAreaDO> areaDOList) {
        if(CollectionUtils.isEmpty(areaDOList)) {
            return new ArrayList<>();
        }

        List<CountryAreaVO> result = areaDOList.stream().filter(area -> area.getLevel().equals(ServiceConfig.COUNTRY_AREA_PROVINCE_LEVEL)).sorted(Comparator.comparing(CountryAreaDO::getCode)).map(area -> new CountryAreaVO(area.getCode(), area.getName(), null)).collect(Collectors.toList());
        result.forEach(province -> province.setChildren(areaDOList.stream().filter(area -> area.getParentCode().equals(province.getCode())).sorted(Comparator.comparing(CountryAreaDO::getCode)).map(area -> new CountryAreaVO(area.getCode(), area.getName(), null)).collect(Collectors.toList())));

        return result;
    }


    /**
     * 根据城市编码列表，将VO转换为BO，用于会员新建、修改下级渠道（MemberAbilityImportServiceImpl)
     * @param upperRelationId 上级会员关系Id
     * @param voList 编码VO列表
     * @param dtoList 省市区域DTO列表
     * @return 转换结果
     */
    public static AgentAreaBO transferToBO(Long upperRelationId, List<AreaCodeVO> voList, List<CountryAreaDTO> dtoList) {
        if(CollectionUtils.isEmpty(voList) || CollectionUtils.isEmpty(dtoList)) {
            return new AgentAreaBO();
        }

        AgentAreaBO agentAreaBO = new AgentAreaBO();
        agentAreaBO.setUpperRelationId(upperRelationId);
        //找出“省”
        List<AreaBO> provinceAreaList = voList.stream().filter(vo -> !StringUtils.hasLength(vo.getCityCode())).map(vo -> {
            AreaBO areaBO = new AreaBO();
            areaBO.setProvinceCode(vo.getProvinceCode());
            areaBO.setCityCode("");
            areaBO.setCity("");
            dtoList.stream().filter(dto -> dto.getCode().equals(vo.getProvinceCode())).findFirst().ifPresent(dto -> areaBO.setProvince(dto.getName()));
            return areaBO;
        }).collect(Collectors.toList());

        //再找“市”
        List<AreaBO> cityAreaList = voList.stream().filter(vo -> provinceAreaList.stream().noneMatch(provinceArea -> provinceArea.getProvinceCode().equals(vo.getProvinceCode())) && StringUtils.hasLength(vo.getCityCode())).map(vo -> {
            AreaBO areaBO = new AreaBO();
            areaBO.setProvinceCode(vo.getProvinceCode());
            dtoList.stream().filter(dto -> dto.getCode().equals(vo.getProvinceCode())).findFirst().ifPresent(dto -> areaBO.setProvince(dto.getName()));
            areaBO.setCityCode(vo.getCityCode());
            dtoList.stream().filter(dto -> dto.getCode().equals(vo.getCityCode())).findFirst().ifPresent(dto -> areaBO.setCity(dto.getName()));
            return areaBO;
        }).collect(Collectors.toList());

        provinceAreaList.addAll(cityAreaList);
        agentAreaBO.setAreas(provinceAreaList.stream().distinct().collect(Collectors.toList()));

        return agentAreaBO;
    }

    public static AgentAreaBO transferToBO(Long upperRelationId, List<AreaCodeVO> voList, AgentAreaBO existAreaBO) {
        if(CollectionUtils.isEmpty(voList) || existAreaBO == null || CollectionUtils.isEmpty(existAreaBO.getAreas())) {
            return new AgentAreaBO();
        }

        AgentAreaBO agentAreaBO = new AgentAreaBO();
        agentAreaBO.setUpperRelationId(upperRelationId);
        //找出“省”
        List<AreaBO> provinceAreaList = voList.stream().filter(vo -> !StringUtils.hasLength(vo.getCityCode())).map(vo -> {
            AreaBO areaBO = new AreaBO();
            areaBO.setProvinceCode(vo.getProvinceCode());
            areaBO.setCityCode("");
            areaBO.setCity("");
            existAreaBO.getAreas().stream().filter(dto -> dto.getProvinceCode().equals(vo.getProvinceCode())).findFirst().ifPresent(dto -> areaBO.setProvince(dto.getProvince()));
            return areaBO;
        }).collect(Collectors.toList());

        //再找“市”
        List<AreaBO> cityAreaList = voList.stream().filter(vo -> provinceAreaList.stream().noneMatch(provinceArea -> provinceArea.getProvinceCode().equals(vo.getProvinceCode())) && StringUtils.hasLength(vo.getCityCode())).map(vo -> {
            AreaBO areaBO = new AreaBO();
            areaBO.setProvinceCode(vo.getProvinceCode());
            existAreaBO.getAreas().stream().filter(dto -> dto.getProvinceCode().equals(vo.getProvinceCode())).findFirst().ifPresent(dto -> areaBO.setProvince(dto.getProvince()));
            areaBO.setCityCode(vo.getCityCode());
            existAreaBO.getAreas().stream().filter(dto -> dto.getCityCode().equals(vo.getCityCode())).findFirst().ifPresent(dto -> areaBO.setCity(dto.getCity()));
            return areaBO;
        }).collect(Collectors.toList());

        provinceAreaList.addAll(cityAreaList);
        agentAreaBO.setAreas(provinceAreaList.stream().distinct().collect(Collectors.toList()));

        return agentAreaBO;
    }

    public static List<AreaBO> transferToBO(List<AreaCodeVO> voList, List<CountryAreaDTO> dtoList) {
        if(CollectionUtils.isEmpty(voList)) {
            return new ArrayList<>();
        }

        if(voList.stream().anyMatch(vo -> vo.getProvinceCode().equals(ServiceConfig.COUNTRY_AREA_TOP_CODE))) {
            return Stream.of(new AreaBO(ServiceConfig.COUNTRY_AREA_TOP_CODE, MemberStringEnum.COUNTRY_AREA_TOP_NAME.getName(), "", "")).collect(Collectors.toList());
        }

        //找出“省”
        List<AreaBO> provinceAreaList = voList.stream().filter(vo -> !StringUtils.hasLength(vo.getCityCode())).map(vo -> {
            AreaBO areaBO = new AreaBO();
            areaBO.setProvinceCode(vo.getProvinceCode());
            areaBO.setCityCode("");
            areaBO.setCity("");
            dtoList.stream().filter(dto -> dto.getCode().equals(vo.getProvinceCode())).findFirst().ifPresent(dto -> areaBO.setProvince(dto.getName()));
            return areaBO;
        }).collect(Collectors.toList());

        //再找“市”
        List<AreaBO> cityAreaList = voList.stream().filter(vo -> provinceAreaList.stream().noneMatch(provinceArea -> provinceArea.getProvinceCode().equals(vo.getProvinceCode())) && StringUtils.hasLength(vo.getCityCode())).map(vo -> {
            AreaBO areaBO = new AreaBO();
            areaBO.setProvinceCode(vo.getProvinceCode());
            dtoList.stream().filter(dto -> dto.getCode().equals(vo.getProvinceCode())).findFirst().ifPresent(dto -> areaBO.setProvince(dto.getName()));
            areaBO.setCityCode(vo.getCityCode());
            dtoList.stream().filter(dto -> dto.getCode().equals(vo.getCityCode())).findFirst().ifPresent(dto -> areaBO.setCity(dto.getName()));
            return areaBO;
        }).collect(Collectors.toList());

        provinceAreaList.addAll(cityAreaList);
        return provinceAreaList.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 将代理省市的名称转换为前端显示
     * @param agentAreaBO 代理区域
     * @return 省市名称拼接
     */
    public static List<String> transferToList(AgentAreaBO agentAreaBO) {
        if(agentAreaBO == null) {
            return new ArrayList<>();
        }

        return transferToList(agentAreaBO.getAreas());
    }

    /**
     * 将AreaBO列表转换为前端编码列表
     * @param areas 省市区域
     * @return 编码列表
     */
    public static List<AreaCodeQueryVO> transferToCodeList(List<AreaBO> areas) {
        if(CollectionUtils.isEmpty(areas)) {
            return new ArrayList<>();
        }

        if(areas.stream().anyMatch(areaBO -> areaBO.getProvince().equals(ServiceConfig.COUNTRY_AREA_TOP_CODE))) {
            return Stream.of(new AreaCodeQueryVO(ServiceConfig.COUNTRY_AREA_TOP_CODE, "")).collect(Collectors.toList());
        } else {
            return areas.stream().map(areaBO -> new AreaCodeQueryVO(areaBO.getProvinceCode(), StringUtils.hasLength(areaBO.getCityCode()) ? areaBO.getCityCode() : "")).collect(Collectors.toList());
        }
    }

    /**
     * 将代理省市的名称转换为前端显示
     * @param areas 区域
     * @return 省市名称拼接
     */
    public static List<String> transferToList(List<AreaBO> areas) {
        if(CollectionUtils.isEmpty(areas)) {
            return new ArrayList<>();
        }

        if(areas.stream().anyMatch(areaBO -> areaBO.getProvince().equals(ServiceConfig.COUNTRY_AREA_TOP_CODE))) {
            return Stream.of(MemberStringEnum.COUNTRY_AREA_TOP_NAME.getName()).collect(Collectors.toList());
        } else {
            return areas.stream().map(areaBO -> !StringUtils.hasLength(areaBO.getCityCode()) ? areaBO.getProvince() : areaBO.getProvince().concat("/").concat(areaBO.getCity())).collect(Collectors.toList());
        }
    }

    /**
     * 将省市列表转换为VO列表，如果有“全国”，则为空
     * @param agentAreaBO 省市列表
     * @return 转换后的列表
     */
    public static List<AreaCodeQueryVO> transferToCodeList(AgentAreaBO agentAreaBO) {
        if(agentAreaBO == null || CollectionUtils.isEmpty(agentAreaBO.getAreas())) {
            return new ArrayList<>();
        }

        List<AreaCodeQueryVO> queryVOList = new ArrayList<>();
        if(agentAreaBO.getAreas().stream().anyMatch(areaBO -> areaBO.getProvince().equals(ServiceConfig.COUNTRY_AREA_TOP_CODE))) {
            AreaCodeQueryVO queryVO = new AreaCodeQueryVO(ServiceConfig.COUNTRY_AREA_TOP_CODE, "");
            queryVOList.add(queryVO);
            return queryVOList;
        }

        return agentAreaBO.getAreas().stream().map(areaBO -> new AreaCodeQueryVO(areaBO.getProvinceCode(), areaBO.getCityCode())).collect(Collectors.toList());
    }

    /**
     * 左侧区域是否不完全包含右侧区域
     * @param source 左侧代理区域
     * @param dest 右侧代理区域
     * @return 是否完全包含
     */
    public static boolean listNotIncluded(AgentAreaBO source, List<AreaCodeVO> dest) {
        if(source == null && dest == null) {
            return false;
        }

        if(source != null && dest == null) {
            return true;
        }

        if(source == null) {
            return true;
        }

        if(CollectionUtils.isEmpty(source.getAreas()) && CollectionUtils.isEmpty(dest)) {
            return false;
        }

        if(CollectionUtils.isEmpty(source.getAreas()) && !CollectionUtils.isEmpty(dest)) {
            return true;
        }

        if(!CollectionUtils.isEmpty(source.getAreas()) && CollectionUtils.isEmpty(dest)) {
            return false;
        }

        //判断省编码
        if(dest.stream().anyMatch(destArea -> source.getAreas().stream().noneMatch(sourceArea -> sourceArea.getProvinceCode().equals(destArea.getProvinceCode())))) {
            return true;
        }

        for (AreaCodeVO areaCodeVO : dest) {
            AreaBO areaBO = source.getAreas().stream().filter(area -> area.getProvinceCode().equals(areaCodeVO.getProvinceCode())).findFirst().orElse(null);
            if(areaBO == null) {
                return true;
            }

            if(StringUtils.hasLength(areaBO.getCityCode()) && (!StringUtils.hasLength(areaCodeVO.getCityCode()) || !areaBO.getCityCode().equals(areaCodeVO.getCityCode()))) {
                return true;
            }
        }

        return false;
    }
}
